<template>
  <div class="h-full overflow-y-auto bg-white">
    <div class="h-full p-5">
      <!-- 页面标题 -->
      <div class="text-xl font-bold mb-5 pb-2.5 border-b">基础查询页面</div>
      <!-- 页面查询区域 -->
      <div class="relative h-16 mb-5" :class="{ 'overflow-hidden': isShrink }">
        <div
          class="absolute z-10 flex justify-between bg-white"
          :class="{ 'shadow-bottom': !isShrink }"
        >
          <!-- 查询表单 -->
          <div class="flex-1">
            <el-form :model="queryForm" inline label-position="top">
              <el-form-item
                v-for="(item, index) in queryFormConfig"
                :key="index"
                class="w-60"
                :label="`${item.fieldLabel}:`"
              >
                <!-- 普通输入框 -->
                <template v-if="!item.fieldType || item.fieldType === 'INPUT'">
                  <el-input
                    class="w-full -mt-2"
                    v-model.trim="queryForm[item.fieldName]"
                    placeholder="请输入"
                    clearable
                  />
                </template>
                <!-- 普通下拉框 -->
                <template v-if="item.fieldType === 'SELECT'">
                  <el-select
                    class="w-full -mt-2"
                    v-model="queryForm[item.fieldName]"
                    placeholder="请选择"
                    filterable
                    clearable
                  >
                    <el-option
                      v-for="(option, index) in item.fieldOptions"
                      :key="index"
                      :label="option.label"
                      :value="option.value"
                    />
                  </el-select>
                </template>
                <!-- 单个日期选择 -->
                <template v-if="item.fieldType === 'DATE'">
                  <el-date-picker
                    class="-mt-2"
                    v-model="queryForm[item.fieldName]"
                    type="date"
                    placeholder="选择日期"
                    value-format="YYYY-MM-DD"
                  />
                </template>
                <!-- 日期范围选择 -->
                <template v-if="item.fieldType === 'RANGE_DATE'">
                  <el-date-picker
                    class="-mt-2"
                    v-model="queryForm[item.fieldName]"
                    type="daterange"
                    range-separator="~"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    value-format="YYYY-MM-DD"
                  />
                </template>
                <!-- 单个日期时间选择 -->
                <template v-if="item.fieldType === 'DATETIME'">
                  <el-date-picker
                    class="-mt-2"
                    v-model="queryForm[item.fieldName]"
                    type="datetime"
                    placeholder="选择时间"
                    value-format="YYYY-MM-DD HH:mm:ss"
                  />
                </template>
                <!-- 日期时间范围选择 -->
                <template v-if="item.fieldType === 'RANGE_DATETIME'">
                  <el-date-picker
                    class="-mt-2"
                    v-model="queryForm[item.fieldName]"
                    type="datetimerange"
                    range-separator="~"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                    value-format="YYYY-MM-DD HH:mm:ss"
                  />
                </template>
              </el-form-item>
            </el-form>
          </div>
          <!-- 表单查询功能区 -->
          <div class="w-60 pt-[22px] flex justify-between">
            <div class="block">
              <el-button type="primary" @click="onQuery">查询</el-button>
              <el-button @click="onReset">重置</el-button>
            </div>
            <div class="block mt-1 mr-4">
              <el-button link @click="isShrink = !isShrink">
                {{ isShrink ? '展开' : '收起' }}
                <el-icon
                  class="ml-1 duration-300 ease-in-out"
                  :style="{
                    transform: isShrink ? 'rotate(180deg)' : 'rotate(0deg)'
                  }"
                  ><ArrowUp />
                </el-icon>
              </el-button>
            </div>
          </div>
        </div>
      </div>
      <!-- 页面列表区域 -->
      <div ref="tableArea" class="block w-full bg-white">
        <!-- 表格头部功能区 -->
        <div class="flex justify-between items-center h-[60px] bg-[#fafafa] border">
          <!-- 头部左侧新增按钮 -->
          <div>
            <el-button type="primary" class="ml-5" @click="openDialog()">
              <el-icon size="18" class="mr-1"><Plus /></el-icon>新增
            </el-button>
            <el-button type="primary" class="ml-5" @click="generateDatas(10)">
              <el-icon size="18" class="mr-1"><Plus /></el-icon>生成10条数据
            </el-button>
          </div>
          <!-- 头部右侧功能按钮 -->
          <div class="flex">
            <el-tooltip
              v-for="(item, index) in tableHeaderConfigs"
              :key="index"
              effect="dark"
              :content="item.label"
              placement="top-start"
            >
              <div v-if="item.icon === 'FullScreen'">
                <span
                  v-if="!isFullScreen"
                  class="flex items-center justify-center w-8 h-8 mr-5 border rounded-full"
                  @click="item.click"
                >
                  <el-icon size="18" color="#9d9d9d">
                    <!-- 通过动态组件实现对不同icon的渲染 -->
                    <component :is="item.icon"></component>
                  </el-icon>
                </span>
                <span
                  v-else
                  class="flex items-center justify-center w-8 h-8 mr-5 border rounded-full"
                >
                  <el-icon size="18" color="#9d9d9d" @click="item.click">
                    <!-- 由于Element Plus没有自带缩小图标，如需更改可自行更改 -->
                    <Close />
                  </el-icon>
                </span>
              </div>
              <span
                v-else
                class="flex items-center justify-center w-8 h-8 mr-5 border rounded-full"
                @click="item.click"
              >
                <el-icon size="18" color="#9d9d9d">
                  <!-- 通过动态组件实现对不同icon的渲染 -->
                  <component :is="item.icon"></component>
                </el-icon>
              </span>
            </el-tooltip>
          </div>
        </div>
        <!-- 表格 -->
        <el-table
          :data="tableData"
          border
          stripe
          header-row-class-name="h-14"
          header-cell-class-name="text-[#333]"
          class="w-full"
        >
          <template #empty>
            <div class="flex flex-col items-center py-3">
              <img :src="nodata" alt="暂无数据" class="mx-auto" />
              <span class="text-center text-gray-400 leading-6 pr-3">暂无数据</span>
            </div>
          </template>
          <!-- 序号，可根据实际需要增删 -->
          <el-table-column
            type="index"
            center
            label="序号"
            align="center"
            fixed="left"
            width="60"
          />
          <!-- 表格列配置 -->
          <el-table-column
            v-for="(item, index) in tableColumnsConfig"
            :key="index"
            align="center"
            :label="item.fieldLabel"
            :prop="item.fieldName"
            :formatter="item.format"
            :min-width="item.width ? item.width : 100"
          />
          <!-- 操作列，可根据实际需要增删 -->
          <el-table-column
            fixed="right"
            label="操作"
            align="center"
            width="120"
            class="flex justify-center"
          >
            <template #default="{ row }">
              <el-button text type="primary" class="!p-0" @click="openDialog(true, row)"
                >编辑</el-button
              >
              <el-popconfirm title="确定要删除吗？" @confirm="onDelete(row)">
                <template #reference>
                  <el-button text type="danger" class="!p-0">删除</el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
        <!-- 表格分页 -->
        <el-pagination
          class="flex justify-end mt-5"
          background
          :page-size="tablePaginationConfig.pageSize"
          :current-page="tablePaginationConfig.currentPage"
          :total="tablePaginationConfig.total"
          layout="total, sizes, prev, pager, next, jumper"
          :page-sizes="[10, 20, 40, 60, 80, 100]"
          @size-change="tablePaginationConfig.handleSizeChange"
          @current-change="tablePaginationConfig.handleCurrentChange"
        />
      </div>
    </div>
    <!-- 新增和编辑弹窗 -->
    <el-dialog
      v-model="dialogVisiable"
      :title="isEdit ? '编辑' : '新增'"
      width="36%"
      @closed="onCloseDialog"
    >
      <el-form :model="addOrModifyForm" inline label-position="top">
        <el-form-item class="w-60 !mb-2" label="司机姓名:">
          <el-input
            class="w-full -mt-2"
            v-model.trim="addOrModifyForm.driverName"
            placeholder="请输入"
            clearable
          />
        </el-form-item>
        <el-form-item class="w-60 !mb-2" label="司机手机号:">
          <el-input
            class="w-full -mt-2"
            v-model.trim="addOrModifyForm.driverPhone"
            placeholder="请输入"
            clearable
          />
        </el-form-item>
        <el-form-item class="w-60 !mb-2" label="车牌号:">
          <el-input
            class="w-full -mt-2"
            v-model.trim="addOrModifyForm.carNumber"
            placeholder="请输入"
            clearable
          />
        </el-form-item>
        <el-form-item class="w-60 !mb-2" label="需求车型:">
          <el-select
            class="w-full -mt-2"
            v-model="addOrModifyForm.carType"
            placeholder="请选择"
            filterable
            clearable
          >
            <el-option
              v-for="(option, index) in carTypeOptions"
              :key="index"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item class="w-60 !mb-2" label="是否计量:">
          <el-switch class="-mt-3" v-model="addOrModifyForm.isMeasure" active-color="#697dff" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="onCloseDialog">取 消</el-button>
        <el-button type="primary" @click="onSubmitData">确 定</el-button>
      </template>
    </el-dialog>
    <!-- 左侧抽屉弹窗 -->
    <el-drawer
      ref="leftDrawer"
      v-model="drawerVisiable"
      title="管理展示字段"
      direction="rtl"
      size="30%"
      @closed="handleDrawerClose"
      destroy-on-close
    >
      <el-radio-group v-model="drawerAreaType">
        <el-radio-button label="查询区" />
        <el-radio-button label="列表区" />
      </el-radio-group>
      <div class="py-5 text-sm">
        选中的字段将会在{{ drawerAreaType }}中显示，默认显示所有{{
          drawerAreaType.slice(0, -1)
        }}字段。 点击上移、下移，或直接拖动字段名称可调整字段展示顺序。
      </div>
      <div v-show="drawerAreaType === '查询区'">
        <div class="bg-[#e9ebf0]">
          <div class="flex justify-between p-2.5 border-b">
            <div class="flex items-center">
              <el-checkbox
                v-model="queryCheckAll"
                :indeterminate="isIndeterminateQuery"
                @change="handleCheckAllChangeQuery"
              />
              <span class="text-sm ml-7">字段名称</span>
            </div>
            <div class="flex items-center">
              <div class="mr-5 text-sm">操作</div>
            </div>
          </div>
        </div>
        <div ref="sortableDrawerQuery">
          <div
            class="even:bg-[#f2f2f2]"
            v-for="(item, index) in queryFormConfigDrawer"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b">
              <div class="flex items-center">
                <el-checkbox
                  v-model="queryFormConfigFilterDrawer[item.fieldName]"
                  @change="handleCheckedFieldChange"
                />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
              <div class="flex items-center justify-between">
                <div
                  class="mr-5 text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed': index === 0,
                    'cursor-pointer': index !== 0
                  }"
                  @click="changeOrderQuery(index, 'up')"
                >
                  上移
                </div>
                <div
                  class="text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed': index === queryFormConfigDrawer.length - 1,
                    'cursor-pointer': index !== queryFormConfigDrawer.length - 1
                  }"
                  @click="changeOrderQuery(index, 'down')"
                >
                  下移
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-show="drawerAreaType === '列表区'">
        <div class="bg-[#e9ebf0]">
          <div class="flex justify-between p-2.5 border-b">
            <div class="flex items-center">
              <el-checkbox
                v-model="tableCheckAll"
                :indeterminate="isIndeterminateTable"
                @change="handleCheckAllChangeTable"
              />
              <span class="text-sm ml-7">字段名称</span>
            </div>
            <div class="flex items-center">
              <div class="mr-5 text-sm">操作</div>
            </div>
          </div>
        </div>
        <div ref="sortableDrawerTable">
          <div
            class="even:bg-[#f2f2f2]"
            v-for="(item, index) in tableColumnsConfigDrawer"
            :key="item.fieldName"
          >
            <div class="flex justify-between p-2.5 border-b">
              <div class="flex items-center">
                <el-checkbox
                  v-model="tableColumnsConfigFilterDrawer[item.fieldName]"
                  @change="handleCheckedFieldChangeTable"
                />
                <span class="text-sm ml-7">{{ item.fieldLabel }}</span>
              </div>
              <div class="flex items-center justify-between">
                <div
                  class="mr-5 text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed': index === 0,
                    'cursor-pointer': index !== 0
                  }"
                  @click="changeOrderTable(index, 'up')"
                >
                  上移
                </div>
                <div
                  class="text-sm text-[#697dff] select-none"
                  :class="{
                    'text-[#a8abb2] cursor-not-allowed':
                      index === tableColumnsConfigDrawer.length - 1,
                    'cursor-pointer': index !== tableColumnsConfigDrawer.length - 1
                  }"
                  @click="changeOrderTable(index, 'down')"
                >
                  下移
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="flex items-center justify-center p-5">
        <el-button @click="handleDrawerClose">取消</el-button>
        <el-button type="primary" @click="saveDrawerData">确定</el-button>
      </div>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, watch, nextTick } from 'vue';
import type { ElDrawer } from 'element-plus';
import Sortable from 'sortablejs';
import type { SortableEvent } from 'sortablejs';
import { ElMessage } from 'element-plus';
import localForage from 'localforage';
import * as API from '@/api/examplePage/StandardPage';
import nodata from '@/assets/images/nodata.png';

/***********************************************
 ***************** 参数配置区 开始 **************
 **********************************************/

interface QueryFormConfigItem {
  /** 字段标签名 */
  fieldLabel: string;
  /** 字段名称 */
  fieldName: string;
  /**
   * 字段类型。
   *
   * - INPUT: 输入框 (默认)
   * - SELECT: 下拉框
   * - DATE: 日期选择器
   * - RANGE_DATE: 日期范围选择器
   * - DATETIME: 日期时间选择器
   * - RANGE_DATETIME: 日期时间范围选择器
   */
  fieldType?: string;
  /**
   * 字段值类型。
   *
   * - STRING: 字符串 (默认)
   * - NUMBER: 数字
   * - DATE: 日期
   * - ARRAY: 数组
   */
  valueType?: string;
  /** 字段选项，当fieldType为SELECT时，需要传入该字段 */
  fieldOptions?: fieldOptionsItem[];
  /** 其他任意属性 */
  [key: string]: unknown;
}
interface fieldOptionsItem {
  label: string;
  value: string | number;
}
// 查询表单配置项
const queryFormConfigInit: QueryFormConfigItem[] = [
  { fieldLabel: '司机姓名', fieldName: 'driverName' },
  { fieldLabel: '司机手机号', fieldName: 'driverPhone' },
  { fieldLabel: '车牌号', fieldName: 'carNumber' },
  { fieldLabel: '需求车型', fieldName: 'carType', fieldType: 'SELECT', fieldOptions: [] },
  {
    fieldLabel: '是否计量',
    fieldName: 'isMeasure',
    fieldType: 'SELECT',
    valueType: 'NUMBER',
    fieldOptions: [
      { label: '是', value: 1 },
      { label: '否', value: 0 }
    ]
  },
  { fieldLabel: '进厂日期', fieldName: 'inDate', fieldType: 'DATE' },
  { fieldLabel: '出厂日期', fieldName: 'outDate', fieldType: 'DATE' },
  { fieldLabel: '创建时间', fieldName: 'createTime', fieldType: 'RANGE_DATE' },
  { fieldLabel: '过磅时间', fieldName: 'weightTime', fieldType: 'RANGE_DATETIME' },
  { fieldLabel: '更新时间', fieldName: 'updateTime', fieldType: 'DATETIME' }
];

interface TableColumnsConfigItem {
  /** 表格列名 */
  fieldLabel: string;
  /** 字段名称 */
  fieldName: string;
  /** 列宽度 */
  width?: number;
  /**
   * 字段格式化函数
   * @param row 当前行数据
   * @param column 当前列数据
   * @param cellValue 当前单元格数据
   * @param index 当前行索引
   */
  format?: Function;
  [key: string]: unknown;
}
// 表格显示字段配置项
const tableColumnsConfigInit: TableColumnsConfigItem[] = [
  { fieldLabel: '司机姓名', fieldName: 'driverName' },
  { fieldLabel: '司机手机号', fieldName: 'driverPhone', width: 160 },
  { fieldLabel: '车牌号', fieldName: 'carNumber' },
  { fieldLabel: '需求车型', fieldName: 'carType' },
  {
    fieldLabel: '是否计量',
    fieldName: 'isMeasure',
    format: (row: Record<string, unknown>) => (row.isMeasure ? '是' : '否')
  },
  { fieldLabel: '进厂日期', fieldName: 'inDate', width: 120 },
  { fieldLabel: '出厂日期', fieldName: 'outDate', width: 120 },
  { fieldLabel: '创建时间', fieldName: 'createTime', width: 180 },
  { fieldLabel: '过磅时间', fieldName: 'weightTime', width: 180 },
  { fieldLabel: '更新时间', fieldName: 'updateTime', width: 180 }
];
/***********************************************
 ***************** 参数配置区 结束 **************
 **********************************************/

/*************************************************
 ***************** 参数初始化区 开始 **************
 *************************************************/

const carTypeOptions = [
  { label: '小型车', value: '小型车' },
  { label: '中型车', value: '中型车' },
  { label: '大型车', value: '大型车' }
];

// 将queryFormConfigInit中fieldName为carType的fieldOptions替换为carTypeOptions
queryFormConfigInit.find((item) => item.fieldName === 'carType')!.fieldOptions = carTypeOptions;

/**************************************************
 **************** 参数初始化区 结束 *****************
 *************************************************/

// 该页面的本地存储的key值，用于存储页面的配置项
const localForageKey = location.pathname;
// 页面的配置项类型
type PageConfig = Record<
  'queryFormOrder' | 'queryFormFilter' | 'tableColumnsOrder' | 'tableColumnsFilter',
  Record<string, number>
>;

const reloadPage = () => {
  getFieldOrderAndFilter();
  onReset();
};

// 查询区和列表区的抽屉区域模板引用
const sortableDrawerQuery = ref<HTMLElement | null>();
const sortableDrawerTable = ref<HTMLElement | null>();

// 查询区配置项的显示顺序
let queryFormConfigOrder: Record<string, number> = {};
// 查询区配置项是否显示
let queryFormConfigFilter: Record<string, number> = {};
// 查询区配置项，用于最终对查询区进行渲染
const queryFormConfig = ref<QueryFormConfigItem[]>([]);
// 查询区配置项的抽屉配置项
const queryFormConfigDrawer = ref<Pick<QueryFormConfigItem, 'fieldName' | 'fieldLabel'>[]>([]);
const queryFormConfigFilterDrawer = ref<Record<string, boolean>>({});

// 列表区配置项的显示顺序
let tableColumnsConfigOrder: Record<string, number> = {};
// 列表区配置项是否显示
let tableColumnsConfigFilter: Record<string, number> = {};
// 列表区配置项，用于最终对列表区进行渲染
const tableColumnsConfig = ref<TableColumnsConfigItem[]>([]);
// 列表区配置项的抽屉配置项
const tableColumnsConfigDrawer = ref<Pick<TableColumnsConfigItem, 'fieldName' | 'fieldLabel'>[]>(
  []
);
const tableColumnsConfigFilterDrawer = ref<Record<string, boolean>>({});

// 计算查询区和列表区实际渲染的配置项
const computeFieldConfig = () => {
  queryFormConfig.value = queryFormConfigInit
    .slice()
    .sort((a, b) => queryFormConfigOrder[a.fieldName] - queryFormConfigOrder[b.fieldName])
    .filter((item) => queryFormConfigFilter[item.fieldName] === 1);
  tableColumnsConfig.value = tableColumnsConfigInit
    .slice()
    .sort((a, b) => tableColumnsConfigOrder[a.fieldName] - tableColumnsConfigOrder[b.fieldName])
    .filter((item) => tableColumnsConfigFilter[item.fieldName] === 1);
};
// 从indexedDB中获取查询区和列表区配置项的显示顺序和是否显示
const getFieldOrderAndFilter = async () => {
  const res: PageConfig | null = await localForage.getItem(localForageKey);
  let shouldSetItem: boolean = false;
  const CurdStandardPage = (res || {}) as PageConfig;

  if (res && 'queryFormOrder' in res) {
    queryFormConfigOrder = res.queryFormOrder;
  } else {
    queryFormConfigInit.forEach((item, index) => {
      queryFormConfigOrder[item.fieldName] = index;
    });
    // 存入CurdStandardPage中的queryFormOrder配置项里
    CurdStandardPage.queryFormOrder = queryFormConfigOrder;
    shouldSetItem = true;
  }
  if (res && 'queryFormFilter' in res) {
    queryFormConfigFilter = res.queryFormFilter;
  } else {
    queryFormConfigInit.forEach((item) => {
      queryFormConfigFilter[item.fieldName] = 1;
    });
    // 存入CurdStandardPage中的queryFormFilter配置项里
    CurdStandardPage.queryFormFilter = queryFormConfigFilter;
    shouldSetItem = true;
  }
  if (res && 'tableColumnsOrder' in res) {
    tableColumnsConfigOrder = res.tableColumnsOrder;
  } else {
    tableColumnsConfigInit.forEach((item, index) => {
      tableColumnsConfigOrder[item.fieldName] = index;
    });
    // 存入CurdStandardPage中的tableColumnsOrder配置项里
    CurdStandardPage.tableColumnsOrder = tableColumnsConfigOrder;
    shouldSetItem = true;
  }
  if (res && 'tableColumnsFilter' in res) {
    tableColumnsConfigFilter = res.tableColumnsFilter;
  } else {
    tableColumnsConfigInit.forEach((item) => {
      tableColumnsConfigFilter[item.fieldName] = 1;
    });
    // 存入CurdStandardPage中的tableColumnsFilter配置项里
    CurdStandardPage.tableColumnsFilter = tableColumnsConfigFilter;
    shouldSetItem = true;
  }
  if (shouldSetItem) {
    await localForage.setItem(localForageKey, CurdStandardPage);
  }
  computeFieldConfig();
};
getFieldOrderAndFilter();

// 从查询区配置项queryFormConfig中获取查询表单的初始值
const queryForm = reactive<Record<string, unknown>>({});
const getQueryForm = () => {
  queryFormConfigInit.forEach((item) => {
    if (
      item.fieldType === 'RANGE_DATE' ||
      item.fieldType === 'RANGE_DATETIME' ||
      item.valueType === 'ARRAY'
    ) {
      queryForm[item.fieldName] = [];
    } else if (!item.valueType || item.valueType === 'STRING') {
      queryForm[item.fieldName] = '';
    } else if (item.valueType === 'NUMBER' || item.valueType === 'DATE') {
      queryForm[item.fieldName] = null;
    } else {
      queryForm[item.fieldName] = null;
    }
  });
};
getQueryForm();

// 表格分页配置项
const tablePaginationConfig = {
  pageSize: 10,
  currentPage: 1,
  total: 0,
  handleSizeChange(value: number) {
    tablePaginationConfig.pageSize = value;
    tablePaginationConfig.currentPage = 1;
    onQuery();
  },
  handleCurrentChange(value: number) {
    tablePaginationConfig.currentPage = value;
    onQuery();
  }
};
const onQuery = () => {
  // 此处用mock数据模拟查询结果
  const params = {
    currentPage: tablePaginationConfig.currentPage,
    pageSize: tablePaginationConfig.pageSize,
    queryData: queryForm
  };
  API.getDatas(params).then((res) => {
    tableData.value = res.data;
    tablePaginationConfig.total = res.total;
  });
};
onQuery();

const onReset = () => {
  getQueryForm();
  tablePaginationConfig.currentPage = 1;
  tablePaginationConfig.pageSize = 10;
  onQuery();
};
const onDelete = (row: Record<string, unknown> & { id: number }) => {
  API.deleteData(row.id).then((res) => {
    ElMessage.success(res.msg);
    onQuery();
  });
};
const dialogVisiable = ref<boolean>(false);
const isEdit = ref<boolean>(false);
const openDialog = (
  _isEdit: boolean = false,
  dataSource: Record<string, unknown> | null = null
) => {
  // 如果数据大于等于200条，则不允许新增
  if (tablePaginationConfig.total >= 200 && !_isEdit) {
    ElMessage.warning('数据量已达上限，不能继续新增');
    return;
  }
  dialogVisiable.value = true;
  isEdit.value = _isEdit;
  if (_isEdit && dataSource) {
    addOrModifyForm.id = dataSource?.id || null;
    addOrModifyForm.driverName = dataSource?.driverName || '';
    addOrModifyForm.driverPhone = dataSource?.driverPhone || '';
    addOrModifyForm.carNumber = dataSource?.carNumber || '';
    addOrModifyForm.carType = dataSource?.carType || '';
    addOrModifyForm.isMeasure = Boolean(dataSource?.isMeasure);
  }
};
const generateDatas = (num: number) => {
  API.generateDatas(num).then((res) => {
    onReset();
    if (res.code === 400) {
      ElMessage.warning(res.msg);
    } else {
      ElMessage.success(res.msg);
    }
  });
};

// 新增和编辑弹窗的表单数据
const addOrModifyForm = reactive<Record<string, unknown>>({
  id: null,
  driverName: '',
  driverPhone: '',
  carNumber: '',
  carType: '',
  isMeasure: false
});
const onCloseDialog = () => {
  // 清空表单数据
  Object.keys(addOrModifyForm).forEach((item) => {
    if (item === 'isMeasure') {
      addOrModifyForm[item] = false;
    } else if (item === 'id') {
      addOrModifyForm[item] = null;
    } else {
      addOrModifyForm[item] = '';
    }
  });
  dialogVisiable.value = false;
};
const onSubmitData = () => {
  const fields = [
    { name: 'driverName', message: '请输入司机姓名' },
    { name: 'driverPhone', message: '请输入司机手机号' },
    { name: 'carNumber', message: '请输入车牌号' },
    { name: 'carType', message: '请选择需求车型' }
  ];

  for (const field of fields) {
    if (!addOrModifyForm[field.name]) {
      ElMessage.warning(field.message);
      return;
    }
  }

  const { id, driverName, driverPhone, carNumber, carType, isMeasure } = addOrModifyForm;
  const params = {
    id,
    driverName,
    driverPhone,
    carNumber,
    carType,
    isMeasure: Number(isMeasure)
  };

  API.modifyData(params).then((res) => {
    ElMessage.success(res.msg);
    onCloseDialog();
    onQuery();
  });
};

const drawerVisiable = ref<boolean>(false);
watch(drawerVisiable, (newVal) => {
  if (newVal) {
    nextTick(() => {
      new Sortable(sortableDrawerQuery.value!, {
        animation: 150,
        onEnd: (evt: SortableEvent) => {
          if (evt.oldIndex === undefined || evt.newIndex === undefined) return;
          const itemMoved = queryFormConfigDrawer.value.splice(evt.oldIndex, 1)[0];
          queryFormConfigDrawer.value.splice(evt.newIndex, 0, itemMoved);
        }
      });
      new Sortable(sortableDrawerTable.value!, {
        animation: 150,
        onEnd: (evt: SortableEvent) => {
          if (evt.oldIndex === undefined || evt.newIndex === undefined) return;
          const itemMoved = tableColumnsConfigDrawer.value.splice(evt.oldIndex, 1)[0];
          tableColumnsConfigDrawer.value.splice(evt.newIndex, 0, itemMoved);
        }
      });
    });
  }
});
const isShrink = ref<boolean>(true);

// 表格头部功能区配置
const isFullScreen = ref<boolean>(false);
const tableArea = ref<HTMLElement | null>(null);
const tableHeaderConfigs = reactive([
  {
    label: '刷新',
    icon: 'Refresh',
    click: () => {
      onQuery();
    }
  },
  {
    label: '全屏',
    icon: 'FullScreen',
    click: () => {
      const element = tableArea.value;
      if (!isFullScreen.value) {
        isFullScreen.value = true;
        element?.classList.add('p-5');
        element?.classList.add('overflow-y-auto');
        element?.requestFullscreen();
      } else {
        document.exitFullscreen();
        if (element?.classList.contains('p-5')) {
          element?.classList.remove('p-5');
          element?.classList.remove('overflow-y-auto');
        }
      }
    }
  },
  {
    label: '设置',
    icon: 'Setting',
    click: async () => {
      // 从indexedDB中获取页面配置项
      const config = (await localForage.getItem(localForageKey)) as PageConfig | null;
      const configOrderQuery = config?.queryFormOrder || {};
      const configFilterQuery = config?.queryFormFilter || {};
      const configOrderTable = config?.tableColumnsOrder || {};
      const configFilterTable = config?.tableColumnsFilter || {};
      // 将页面配置项赋值到抽屉组件的配置项中
      queryFormConfigInit.forEach((item) => {
        queryFormConfigDrawer.value[configOrderQuery[item.fieldName]] = item;
        queryFormConfigFilterDrawer.value[item.fieldName] = configFilterQuery[item.fieldName]
          ? true
          : false;
      });
      tableColumnsConfigInit.forEach((item) => {
        tableColumnsConfigDrawer.value[configOrderTable[item.fieldName]] = item;
        tableColumnsConfigFilterDrawer.value[item.fieldName] = configFilterTable[item.fieldName]
          ? true
          : false;
      });
      handleCheckedFieldChange();
      handleCheckedFieldChangeTable();
      drawerVisiable.value = true;
    }
  }
]);

// 当执行exitFullscreen时，isFullScreen设为false
document.addEventListener('fullscreenchange', () => {
  const element = tableArea.value;
  if (!document.fullscreenElement) {
    isFullScreen.value = false;
    if (element?.classList.contains('p-5')) {
      element?.classList.remove('p-5');
    }
    if (element?.classList.contains('overflow-y-auto')) {
      element?.classList.remove('overflow-y-auto');
    }
  }
});

// 抽屉查询区选择和拖拽逻辑
const queryCheckAll = ref<boolean>(false);
const isIndeterminateQuery = ref<boolean>(false);
const handleCheckAllChangeQuery = (val: boolean) => {
  if (val) {
    Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
      queryFormConfigFilterDrawer.value[item] = true;
    });
  } else {
    Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
      queryFormConfigFilterDrawer.value[item] = false;
    });
  }
  isIndeterminateQuery.value = false;
};

// 抽屉列表区选择和拖拽逻辑
const tableCheckAll = ref<boolean>(false);
const isIndeterminateTable = ref<boolean>(false);
const handleCheckAllChangeTable = (val: boolean) => {
  if (val) {
    Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
      tableColumnsConfigFilterDrawer.value[item] = true;
    });
  } else {
    Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
      tableColumnsConfigFilterDrawer.value[item] = false;
    });
  }
  isIndeterminateTable.value = false;
};

const handleCheckedFieldChange = () => {
  let checkedCount = 0;
  Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
    queryFormConfigFilterDrawer.value[item] ? checkedCount++ : '';
  });
  const totalCount = Object.keys(queryFormConfigFilterDrawer.value).length;
  queryCheckAll.value = checkedCount === totalCount;
  isIndeterminateQuery.value = checkedCount > 0 && checkedCount < totalCount;
};
const changeOrderQuery = (index: number, type: 'up' | 'down') => {
  if (type === 'up') {
    if (index === 0) return;
    const temp = queryFormConfigDrawer.value[index];
    queryFormConfigDrawer.value[index] = queryFormConfigDrawer.value[index - 1];
    queryFormConfigDrawer.value[index - 1] = temp;
  } else {
    if (index === queryFormConfigDrawer.value.length - 1) return;
    const temp = queryFormConfigDrawer.value[index];
    queryFormConfigDrawer.value[index] = queryFormConfigDrawer.value[index + 1];
    queryFormConfigDrawer.value[index + 1] = temp;
  }
};

const handleCheckedFieldChangeTable = () => {
  let checkedCount = 0;
  Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
    tableColumnsConfigFilterDrawer.value[item] ? checkedCount++ : '';
  });
  const totalCount = Object.keys(tableColumnsConfigFilterDrawer.value).length;
  tableCheckAll.value = checkedCount === totalCount;
  isIndeterminateTable.value = checkedCount > 0 && checkedCount < totalCount;
};
const changeOrderTable = (index: number, type: 'up' | 'down') => {
  if (type === 'up') {
    if (index === 0) return;
    const temp = tableColumnsConfigDrawer.value[index];
    tableColumnsConfigDrawer.value[index] = tableColumnsConfigDrawer.value[index - 1];
    tableColumnsConfigDrawer.value[index - 1] = temp;
  } else {
    if (index === tableColumnsConfigDrawer.value.length - 1) return;
    const temp = tableColumnsConfigDrawer.value[index];
    tableColumnsConfigDrawer.value[index] = tableColumnsConfigDrawer.value[index + 1];
    tableColumnsConfigDrawer.value[index + 1] = temp;
  }
};

// 对左侧抽屉的引用
const leftDrawer = ref<InstanceType<typeof ElDrawer>>();
// 关闭左侧抽屉
const handleDrawerClose = () => {
  drawerAreaType.value = '查询区';
  leftDrawer.value?.handleClose();
};
// 保存左侧抽屉的配置项
const saveDrawerData = async () => {
  const CurdStandardPage = ((await localForage.getItem(localForageKey)) as PageConfig) || {};
  let fieldOrder: Record<string, number> = {};
  let fieldFilter: Record<string, number> = {};
  let fieldOrderTable: Record<string, number> = {};
  let fieldFilterTable: Record<string, number> = {};

  queryFormConfigDrawer.value.forEach((item, index) => {
    fieldOrder[item.fieldName] = index;
  });
  Object.keys(queryFormConfigFilterDrawer.value).forEach((item) => {
    fieldFilter[item] = queryFormConfigFilterDrawer.value[item] ? 1 : 0;
  });
  tableColumnsConfigDrawer.value.forEach((item, index) => {
    fieldOrderTable[item.fieldName] = index;
  });
  Object.keys(tableColumnsConfigFilterDrawer.value).forEach((item) => {
    fieldFilterTable[item] = tableColumnsConfigFilterDrawer.value[item] ? 1 : 0;
  });

  CurdStandardPage.queryFormOrder = fieldOrder;
  CurdStandardPage.queryFormFilter = fieldFilter;
  CurdStandardPage.tableColumnsOrder = fieldOrderTable;
  CurdStandardPage.tableColumnsFilter = fieldFilterTable;

  await localForage.setItem(localForageKey, CurdStandardPage);
  handleDrawerClose();
  reloadPage();
};

// 表格数据-模拟
const tableData = ref<Record<string, unknown>[]>([]);

// 左侧抽屉弹窗配置项
const drawerAreaType = ref<string>('查询区');
</script>

<style lang="scss" scoped>
:deep(.el-form-item .el-date-editor) {
  --el-date-editor-width: 100%;
}
.el-button {
  --el-color-primary: #697dff;
}
.el-radio-group {
  --el-color-primary: #697dff;
}
.el-table {
  --el-fill-color-light: #e8f3fe;
  --el-fill-color-lighter: #f2f2f2;
  --el-table-header-bg-color: #e9ebf0;
}
.el-checkbox {
  --el-color-primary: #697dff;
}
.el-pagination {
  --el-color-primary: #697dff;
}
:global(.el-drawer__header) {
  border-bottom: 1px solid #ddd;
  margin: 0;
  padding: 20px;
}
</style>
